import logging
from contextlib import contextmanager
from copy import deepcopy
from threading import Lock

from .database import SessionLocal, engine

from . import models

models.Base.metadata.create_all(bind=engine)
DBThreadLock = Lock()
LOG=logging.getLogger()

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


@contextmanager
def session_maker():
    db = SessionLocal()
    try:
        yield db
        db.commit()
    except:
        db.rollback()
        raise
    finally:
        db.close()


def get_order(android_ip: str) -> models.Order:
    with session_maker() as session:
        data = session.query(models.Order).filter(models.Order.android_ip == android_ip).first()
        return deepcopy(data)


def get_order_by_user(user: str) -> models.Order:
    with session_maker() as session:
        data = session.query(models.Order).filter(models.Order.user == user).first()
        return deepcopy(data)


def get_orders(limit: int = 100) -> [models.Order]:
    with session_maker() as session:
        data = session.query(models.Order).limit(limit).all()
        return deepcopy(data)


def update_order(android_ip: str, update_value: dict) -> models.Order:
    with DBThreadLock:
        with session_maker() as session:
            db_order = session.query(models.Order).filter(models.Order.android_ip == android_ip).first()
            for key, value in update_value.items():
                setattr(db_order, key, value)
            session.add(db_order)
            session.commit()
            session.refresh(db_order)
            return deepcopy(db_order)


# def create_order(order: model.TaoBaoOrderTask) -> models.Order:
#     with DBThreadLock:
#         with session_maker() as session:
#             db_order = models.Order(**order.dict())
#             session.add(db_order)
#             session.commit()
#             session.refresh(db_order)
#             return deepcopy(db_order)


def delete_order(android_ip: str):
    with DBThreadLock:
        with session_maker() as session:
            orders = session.query(models.Order).filter(models.Order.android_ip == android_ip).all()
            for order in orders:
                session.delete(order)
                LOG.info('delete db android_ip={} order {}'.format(order, order.to_dict()))
            session.commit()
